import Toast from '../../../component/Toast';
import { uuid } from '../../../util/code'
import { clone } from '../../../util/utils'
import { register } from '../../login/service/registerService';
import { pageUser, saveUser, updateUser, synRole } from '../service/userService';
import { listRoleByUserId, pageRole } from '../service/roleService';

const defaultState = {
	
	list: [],
	pageNum: undefined,
	pageSize: undefined,
	total: undefined,
	editBuf: {},
	
	current: undefined,
	left: [],
	right: [],
	visible: false,
	
}

export default {

	namespace: 'user',

	state: {...defaultState},

	reducers: {
		
		reset(state, {tab}) {
			return {...defaultState}
		},
		
		setList(state, {list}) {
			return {...state, ...{list}}
		},
		
		setPageNum(state, {pageNum}) {
			return {...state, ...{pageNum}}
		},
		
		setPageSize(state, {pageSize}) {
			return {...state, ...{pageSize}}
		},
		
		setTotal(state, {total}) {
			return {...state, ...{total}}
		},
		
		setEditBuf(state, {editBuf}) {
			return {...state, ...{editBuf}}
		},
		
		putEditBuf(state, {key, value}) {
			state = clone(state)
			state.editBuf[clone(key)] = clone(value)
			return state
		},
		
		setCurrent(state, {current}) {
			return {...state, ...{current}}
		},
		
		setLeft(state, {left}) {
			return {...state, ...{left}}
		},
		
		setRight(state, {right}) {
			return {...state, ...{right}}
		},
		
		setVisible(state, {visible}) {
			return {...state, ...{visible}}
		},
		
	},
	
	effects: {
		
		*flushRecord({record, key}, {select, put}) {
			let {list} = yield select(state => state.user)
			// save时使用uuid的key
			key = key || record.key
			record.key = record.userId
			list = clone(list);
			for (let i = 0; i < list.length; i ++) {
				if (list[i] && list[i].key == key) {
					list.splice(i, 1, record)
					yield put({type: 'setList', list})
					return
				}
			}
		},
		
		*pageUser({pageNum, pageSize}, {select, put}) {
			let res = yield pageUser({pageNum, pageSize})
			if (res.code == 1) {
				let pageInfo = res.data
				if (pageInfo && pageInfo.list) {
					// 添加key字段
					for (let item of pageInfo.list) {
						if (!item.key)
							item.key = item.userId
					}
					yield put({type: 'setList', list: pageInfo.list})
					yield put({type: 'setTotal', total: pageInfo.total})
					yield put({type: 'setPageNum', pageNum: pageInfo.pageNum})
					yield put({type: 'setPageSize', pageSize: pageInfo.pageSize})
				}
			} else {
				res.msg && Toast.show(res.msg)
			}
		},
		
		*edit({record}, {select, put}) {
			let {list} = yield select(state => state.user)
			list = clone(list)
			if (list && list.length > 0) {
				let user = findListByKey(list, record.key)
				if (user) {
					// 存入缓存
					yield put({
						type: 'putEditBuf', 
						key: user.key,
						value: user
					})
					// 修改内容
					user.editable = true
					yield put({type: 'setList', list})
				}
			}
		},
		
		*editRecord({record, key, value}, {select, put}) {
			let {list} = yield select(state => state.user)
			let user = findListByKey(list, record.key)
			if (user) {
				user[key] = value
				yield put({type: 'setList', list})
			}
		},
		
		*cancel({record}, {select, put}) {
			let {list, editBuf} = yield select(state => state.user)
			list = clone(list)
			if (list && list.length > 0) {
				let user
				let i = 0
				for (; i < list.length; i ++) {
					if (list[i] && list[i].key == record.key) {
						user = list[i]
						break
					}
				}
				if (user) {
					if (user.userId) {
						let buf = editBuf[user.key];
						// 同步回之前缓存
						for (let key in user) {
							user[key] = buf[key]
						}
						user.editable = false
						// 删除buf
						editBuf = clone(editBuf)
						delete editBuf[user.key]
						yield put({type: 'setEditBuf', editBuf})
					} else {
						// 新建的record
						// 删除
						list.splice(i, 1);
					}
					yield put({type: 'setList', list})
				}
			}
		},
		
		*save({key}, {select, put}) {
			let {list, editBuf, total} = yield select(state => state.user)
			if (list && list.length > 0) {
				let record = findListByKey(list, key)
				if (record) {
					let res
					if (!record.username && !record.email && !record.mobileOhone) {
						return Toast.show('用户名、邮箱、手机号不能同时为空')
					}
					if (record.userId) {
						// update
						res = yield updateUser(record)
					} else {
						// save
						res = yield register(record)
						if (res.code == 1) {
							yield put({type: 'setTotal', total: total + 1})
						}
					}
					if (res.code == 1 && res.data) {
						// 局部刷新
						yield put({type: 'flushRecord', record: res.data, key})
					} else {
						Toast.show(res.msg)
					}
				}
			}
		},
		
		*remove({userId}, {select, put}) {
			let res = yield updateUser({userId, status: 1})
			if (res.code == 1) {
				let record = res.data
				if (record) {
					record.key = record.userId
					yield put({type: 'flushRecord', record})
				}
			} else {
				Toast.show(res.msg)
			}
		},
		
		*add(action, {select, put}) {
			let {list} = yield select(state => state.user)
			list = clone(list)
			if (list) {
				list.splice(0, 0, {key: uuid(), editable: true});
				yield put({type: 'setList', list})
			}
		},
		
		*showGrant({visible, userId}, {select, put}) {
			let left = []
			let right = []
			if (visible) {
				let allRes = yield pageRole({pageNum: 1, pageSize: 99999999})
				let ownerRes = yield listRoleByUserId({userId})
				
				if (allRes.code != 1) 
					return Toast.show(allRes.msg)
				if (ownerRes.code != 1) 
					return Toast.show(ownerRes.msg)
					
				let all = allRes.data.list
				let owner = ownerRes.data
				
				let ownerMap = {}
				for (let item of owner) {
					ownerMap[item.roleId] = item
				}
				
				for (let item of all) {
					left.push({
						key: item.roleId,
					  	title: item.role,
					  	description: item.description,
					  	disabled: false
					})
					if (ownerMap[item.roleId]) 
						right.push(item.roleId)
				}
				yield put({type: 'setCurrent', current: userId})
			}
			yield put({type: 'setLeft', left})
			yield put({type: 'setRight', right})
			yield put({type: 'setVisible', visible})
		},
		
		*saveGrant(action, {select, put}) {
			let {right, current} = yield select(state => state.user)
			let res = yield synRole({userId: current, roleIds: right})
			if (res.code == 1) {
				Toast.show('修改成功')
				yield put({type: 'setVisible', visible: false})
			} else {
				Toast.show(res.msg)
			}
		}
		
	}

}

function findListByKey(list, key) {
	if (list && list.length > 0) {
		for (let i = 0; i < list.length; i ++) {
			if (list[i] && list[i].key == key)
				return list[i]
		}
	}
}
